﻿#include "CMutexRecursive.h"

namespace lampe{
namespace thread{

CMutexRecursive::CMutexRecursive(){
	locked=false;
#ifdef _IRR_COMPILE_WITH_X11_DEVICE_
	pthread_mutexattr_t attr;
    pthread_mutexattr_init(&attr);
    pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
    pthread_mutex_init(&m_mutex, &attr);
    pthread_mutexattr_destroy(&attr);
#endif
#ifdef _IRR_WINDOWS_
	m_mutex = CreateMutex(NULL, FALSE, NULL);
#endif
	lockCount=0;
}

CMutexRecursive::~CMutexRecursive(){
#ifdef _IRR_COMPILE_WITH_X11_DEVICE_
	pthread_mutex_destroy(&m_mutex);
#endif
#ifdef _IRR_WINDOWS_
	CloseHandle(m_mutex);
#endif
}

void CMutexRecursive::lock(){
	lockCount++;
#ifdef _IRR_WINDOWS_
	WaitForSingleObject(m_mutex, INFINITE);
#endif
#ifdef _IRR_COMPILE_WITH_X11_DEVICE_
	pthread_mutex_lock(&m_mutex);
#endif
}
void CMutexRecursive::unlock(){
	if (lockCount==0)
		return;
	lockCount--;
#ifdef _IRR_WINDOWS_
	ReleaseMutex(m_mutex);
#endif
#ifdef _IRR_COMPILE_WITH_X11_DEVICE_
	pthread_mutex_unlock(&m_mutex);
#endif

}

bool CMutexRecursive::isLocked(){
	return lockCount>0;
}

IMutex*createRecursiveMutex(){
	return new CMutexRecursive();
}

}//namespace thread
}//namespace irr
